[9주차/해피잭] 워크북 제출합니다#21
Conversation
| abstract updateUser( | ||
| userId: bigint, | ||
| data: Omit<UserUpdateProfileData, 'preferences'>, | ||
| ): Promise<void>; | ||
| abstract replacePreferences( | ||
| userId: bigint, | ||
| foodCategoryIds: bigint[], | ||
| ): Promise<void>; |
There was a problem hiding this comment.
추상 interface를 적극적으로 활용하시는게 좋습니다!
| */ | ||
| @Patch('me') | ||
| @SuccessResponse(StatusCodes.OK, 'OK') | ||
| @Middlewares(validationMiddleware(UserUpdateProfileRequest)) |
| public async updateMyProfile( | ||
| @Request() req: ExpressRequest, | ||
| ): Promise<Record<string, unknown>> { | ||
| if (!req.user) { |
There was a problem hiding this comment.
ts 설정에 따라서 바로 req.user를 접근하려고 하면 오류가 발생할 수 도 있습니다.
전역 타입 express 확장 파일을 선언해주세요
declare global {
namespace Express {
interface Request {
user?: {
userId: number;
};
}
}
}
export {};| if (result.count === 0) { | ||
| throw new AppError( | ||
| USER_ERROR_CODE.USER_NOT_FOUND, | ||
| '존재하지 않는 사용자입니다.', | ||
| StatusCodes.NOT_FOUND, | ||
| ); | ||
| } |
There was a problem hiding this comment.
내가 업데이트를 수행한 사용자가 존재하는지 여부는 service 레이어에서 확인하고 repo에서는 db 접근만 하도록 역할을 나누는게 좋아보입니다
| userId: bigint, | ||
| foodCategoryIds: bigint[], | ||
| ): Promise<void> { | ||
| await prisma.$transaction(async (tx) => { |
There was a problem hiding this comment.
prisma transaction을 활용하신것 아주 좋습니다. 이를 더 확장해 service에서 transaction을 관리하는 방법인 AsyncLocalStorage를 찾아보시면 좋을거 같습니다
| where: { user_id: userId }, | ||
| }); | ||
|
|
||
| for (const foodCategoryId of foodCategoryIds) { |
There was a problem hiding this comment.
현재 푸드 카테고리별로await를 호출해 병목이 발생할수 있습니다. createMany를 활용해 반복문을 사용하지 않는 방법을 고려해주세요
| export const generateAccessToken = (user: { id: bigint; email: string }) => { | ||
| return jwt.sign( | ||
| { id: user.id.toString(), email: user.email }, | ||
| process.env.JWT_SECRET!, |
There was a problem hiding this comment.
환경변수를 !으로 단언하기 보다 변수로 선언해 존재하는지를 예외처리하는것이 좋아보입니다
const secrete = process.env.Secrete
if(!secrete)
throw new Error("환경변수 Secrete이 선언되지 않았습니다"| } | ||
| }; | ||
|
|
||
| const googleVerify = async (profile: Profile): Promise<AuthUser> => { |
There was a problem hiding this comment.
구글로그인 인증과 동시에 사용자 회원가입을 진행하는것 보다 /google에서 로그인을 진행하고 만약 해당 사용자가 회원가입 되지 않은 사용자라면 json 응답에 응답 종류와 ticket으로 /google/register 라우터로 리다이렉트 시키는방식으로 구현하는게 좋을것 같습니다
| app.get('/login-failed', (_req: Request, res: Response) => { | ||
| res.status(401).json({ success: false, message: '소셜 로그인에 실패했습니다.' }); | ||
| }); | ||
|
|
There was a problem hiding this comment.
이 부분도 배운대로 auth class로 tsoa로 구현해주시면 좋을거 같습니다
✅ 실습 체크리스트
✅ 컨벤션 체크리스트
📌 주안점